/**
 * POST /api/offers/sepa/send — standalone SEPA mandate: render the fillable
 * mandate, create a signing request (kind 'sepa', link /sepa/<token>), mail
 * the customer, attach the blank mandate to the record, log an activity and
 * remember the setup on offer_conditions.sepa.
 *
 * Body: { source: 'lead'|'partner', recordId, recordUu?, language: 'de'|'en',
 *         scheme: 'B2B'|'CORE', recurring, prenotificationDays, mandateReference?,
 *         customer: { company, contactName, street, zip, city, country },
 *         signing: { expiryDays, expiresAt }, email: { to, cc, subject, message } }
 */
import refreshTokenHelper from '../../../utils/refreshTokenHelper'
import errorHandlingHelper from '../../../utils/errorHandlingHelper'
import forceLogoutHelper from '../../../utils/forceLogoutHelper'
import { buildSepaMandatePdf, sepaFilename } from '../../../utils/offers/sepaPdf'
import { buildMandateData, sepaLink, NOTIFY_EMAIL } from '../../../utils/offers/sepaMandate'
import { createSigningRequest, isSigningAvailable, writeSigningFile, sha256Hex } from '../../../utils/offers/contractSigningDb'
import { mailTransport, resolveSigningExpiry, brandedEmail, escapeHtml, formatDateHuman } from '../../../utils/offers/contractSigning'
import { attachToStrapi } from '../../../utils/inbox/strapiAttach'
import { logContactActivity, strapiPublicFileUrl } from '../../../utils/offers/contactActivity'
import { saveOfferConditions } from '../../../utils/offers/offerConditions'

const handleFunc = async (event: any, authToken: string | null = null) => {
  const token = authToken ?? await getTokenHelper(event)
  if (!token) return { status: 401, message: 'Not authenticated' }
  if (!isSigningAvailable()) return { status: 503, message: 'Signing store not available' }
  const body: any = await readBody(event)
  const language = body?.language === 'en' ? 'en' : 'de'
  const en = language === 'en'
  const source = body?.source === 'lead' ? 'lead' : 'partner'
  const recordId = Number(body?.recordId) || 0
  const c = body?.customer || {}
  const toEmail = String(body?.email?.to || '').trim()
  if (!/.+@.+\..+/.test(toEmail)) return { status: 400, message: en ? 'Recipient e-mail is required' : 'Empfänger-E-Mail ist erforderlich' }
  if (!String(c.company || '').trim()) return { status: 400, message: en ? 'Company is required' : 'Firma ist erforderlich' }
  const ccList = String(body?.email?.cc || '').split(/[;,]/).map((s: string) => s.trim()).filter((s: string) => /.+@.+\..+/.test(s))

  const debtor = { company: c.company || '', accountHolder: c.company || '', street: c.street || '', zipCity: [c.zip, c.city].filter(Boolean).join(' '), country: c.country || '' }
  const mandate = buildMandateData(source, recordId, { scheme: body?.scheme, recurring: body?.recurring !== false, prenotificationDays: Number(body?.prenotificationDays) || undefined, mandateReference: body?.mandateReference }, debtor)
  const buffer = await buildSepaMandatePdf({ data: mandate, language, filled: debtor })
  const filename = sepaFilename(language, mandate.mandateReference)

  const expiresAt = resolveSigningExpiry(body?.signing || {})
  const req = createSigningRequest({
    kind: 'sepa',
    source,
    recordId: recordId > 0 ? recordId : 0,
    recordUu: body?.recordUu || undefined,
    company: String(c.company),
    contactName: String(c.contactName || ''),
    email: toEmail,
    language,
    payload: { source, recordId, customer: c, mandate },
    documents: [{ key: 'sepa', title: en ? 'SEPA Direct Debit Mandate' : 'SEPA-Lastschriftmandat', filename, sha256: sha256Hex(buffer), size: buffer.length }],
    createdBy: Number(getCookie(event, 'logship_user_id')) || null,
    expiresAt
  })
  writeSigningFile(req.token, filename, buffer)
  const link = sepaLink(req.token)
  const warnings: string[] = []

  // mail
  const greeting = en ? `Dear ${escapeHtml(c.contactName || c.company)},` : `Guten Tag ${escapeHtml(c.contactName || c.company)},`
  const msg = String(body?.email?.message || '').trim()
  const intro = msg ? escapeHtml(msg).replace(/\n/g, '<br>') : (en
    ? `please grant us the SEPA direct debit mandate for the fees of our fulfilment service. Enter the account holder and IBAN online and sign — it only takes a minute.`
    : `bitte erteilen Sie uns das SEPA-Lastschriftmandat für die Entgelte unserer Fulfillment-Leistungen. Tragen Sie Kontoinhaber und IBAN online ein und unterschreiben Sie – das dauert nur eine Minute.`)
  const cta = `<p style="margin:18px 0;"><a href="${link}" style="display:inline-block;background:#F15924;color:#fff;text-decoration:none;font-weight:700;padding:12px 22px;border-radius:8px;">${en ? 'Complete SEPA mandate online' : 'SEPA-Mandat online erteilen'}</a></p><p style="color:#6b7280;font-size:13px;">${en ? 'Link valid until' : 'Link gültig bis'} ${escapeHtml(formatDateHuman(expiresAt, language))} · ${en ? 'Mandate reference' : 'Mandatsreferenz'} ${escapeHtml(mandate.mandateReference)}</p>`
  try {
    await mailTransport().sendMail({
      from: NOTIFY_EMAIL,
      to: toEmail,
      cc: ccList.length ? ccList.join(', ') : undefined,
      subject: String(body?.email?.subject || '').trim() || (en ? `SEPA direct debit mandate – ${c.company}` : `SEPA-Lastschriftmandat – ${c.company}`),
      text: `${msg || (en ? 'Please complete the SEPA mandate online:' : 'Bitte erteilen Sie das SEPA-Mandat online:')}\n${link}`,
      html: brandedEmail(en ? 'SEPA direct debit mandate' : 'SEPA-Lastschriftmandat', `<p>${greeting}</p><p>${intro}</p>${cta}`, en ? 'The mandate is attached as a fillable PDF as well.' : 'Das Mandat liegt zusätzlich als ausfüllbares PDF bei.'),
      attachments: [{ filename, content: buffer, contentType: 'application/pdf' }]
    })
  } catch (err: any) {
    console.error('[SEPA] send mail failed:', err?.message || err)
    warnings.push(en ? 'E-mail could not be sent (link created)' : 'E-Mail konnte nicht gesendet werden (Link wurde erstellt)')
  }

  // attach blank mandate + conditions + activity (fail-soft)
  let attachedUrl = ''
  try {
    if (recordId > 0) {
      const up = await attachToStrapi(event, token, { tableName: source === 'lead' ? 'Lead_User' : 'C_BPartner', recordId, recordUu: body?.recordUu || undefined, buffer, filename, mimeType: 'application/pdf' })
      attachedUrl = strapiPublicFileUrl(up.fileUrl)
    }
  } catch (err: any) {
    console.error('[SEPA] attach blank failed:', err?.message || err)
  }
  try {
    if (recordId > 0) await saveOfferConditions(event, token, source, recordId, 'sepa', { language, scheme: mandate.scheme, recurring: mandate.recurring, prenotificationDays: mandate.creditor.prenotificationDays, mandateReference: mandate.mandateReference, lastSend: { at: new Date().toISOString(), to: toEmail, token: req.token, expiresAt } })
  } catch (err: any) {
    console.error('[SEPA] conditions save failed:', err?.message || err)
  }
  try {
    await logContactActivity(event, token, {
      source, recordId, type: 'EM', contactEmail: toEmail,
      description: en ? `SEPA mandate sent: ${mandate.mandateReference}` : `SEPA-Mandat gesendet: ${mandate.mandateReference}`,
      comments: [
        en ? `SEPA ${mandate.scheme} direct debit mandate ${filename} e-mailed to ${toEmail}${ccList.length ? ` (CC: ${ccList.join(', ')})` : ''}.` : `SEPA-${mandate.scheme === 'B2B' ? 'Firmenlastschrift' : 'Basislastschrift'}mandat ${filename} per E-Mail an ${toEmail}${ccList.length ? ` (CC: ${ccList.join(', ')})` : ''} gesendet.`,
        en ? `Mandate reference: ${mandate.mandateReference}` : `Mandatsreferenz: ${mandate.mandateReference}`,
        en ? `Online mandate link (valid until ${formatDateHuman(expiresAt, 'en')}): ${link}` : `Online-Mandats-Link (gültig bis ${formatDateHuman(expiresAt, 'de')}): ${link}`
      ].join('\n'),
      documents: attachedUrl ? [{ title: en ? 'SEPA mandate (blank, PDF)' : 'SEPA-Mandat (Vorlage, PDF)', url: attachedUrl }] : []
    })
  } catch (err: any) {
    console.error('[SEPA] activity failed:', err?.message || err)
  }

  return { status: 200, message: en ? 'SEPA mandate sent' : 'SEPA-Mandat gesendet', filename, mandateReference: mandate.mandateReference, link, expiresAt, token: req.token, warning: warnings.join(' · ') || undefined }
}

export default defineEventHandler(async (event) => {
  let data: any = {}
  try {
    data = await handleFunc(event)
  } catch (err: any) {
    try {
      const authToken = await refreshTokenHelper(event)
      data = await handleFunc(event, authToken)
    } catch (error: any) {
      data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
      forceLogoutHelper(event, data)
    }
  }
  return data
})
